//#include "udp_includes.h"
#include "../includes.h"

UDP_DAEMON_ udp;

IPC_Header_T			buf_ipc;
KTI_SubData_Report_T 	buf_report;

_st_Download_File stDF={1, };

int GetDownloadTotalFrame()			{ return stDF.totalBlock; 		}
int GetDownloadCurrentFrame()		{ return stDF.currentBlock; 	}
char *GetDownloadCurrentPointer()	{ return (stDF.p+stDF.filepos); }
int GetDownloadCurrentSize()		{ return stDF.size_sent; 		}


//hmlee - arm only
#define __NR_ioprio_set		314
#define __NR_ioprio_get		315
enum {
	IOPRIO_CLASS_NONE,
	IOPRIO_CLASS_RT,
	IOPRIO_CLASS_BE,
	IOPRIO_CLASS_IDLE,
};

enum {
	IOPRIO_WHO_PROCESS = 1,
	IOPRIO_WHO_PGRP,
	IOPRIO_WHO_USER,
};
#define IOPRIO_CLASS_SHIFT	13
#define SCHED_IDLE	 5
#define SCHED_BATCH	 3
//hmlee - glibc doesn't have wrapper function for ioprio_set(get)
static inline int ioprio_set(int which, int who, int ioprio)
{
	return syscall(__NR_ioprio_set, which, who, ioprio);
}

static inline int ioprio_get(int which, int who)
{
	return syscall(__NR_ioprio_get, which, who);
}

extern char **environ;
inline int set_lowest_sched(void)
{
struct sched_param schedp;
int pri_old = 0;
int pri_new = 0;
int pid = 0;

	memset(&schedp, 0, sizeof(schedp));
	schedp.sched_priority = 0;
	if (sched_setscheduler(0, SCHED_IDLE, &schedp)!=0){
		LogItString(LOG_CATA1_NORM, LOG_CATA2_FAIL, "sched_setscheduler fork");
	}

	nice(19);

	pid = getpid();
	pri_old = ioprio_get(IOPRIO_WHO_PROCESS, pid);
	pri_new = IOPRIO_CLASS_IDLE<<IOPRIO_CLASS_SHIFT;
	if(ioprio_set(IOPRIO_WHO_PROCESS, pid, pri_new) == -1){
		//LogItString(strerror(errno));
	}
	else{
		//LogItString2("ioprio: ", pri_old, pri_new);
	}
	return 0;
}

int bInitUdp=0;
int init_udpd(void)
{
	strcpy( GetSerialNumber() ,"RCU-G00000000" );
	init_user_cfg();
	read_user_cfg();
	//strcpy( str_ip_server, DEFAULT_SERVER_IP );
	//strncpy( str_ip_server, sicf.v[M_IP_CFG_Remote_IP_INDEX],NET_ADDRESS_LENGTH );
	//udp_printf("remote_ip:%s, remote_port:%s \n", sicf.v[M_IP_CFG_Remote_IP_INDEX], sicf.v[M_IP_CFG_Remote_PORT_INDEX] );
	memset(&buf_ipc		,0	,sizeof(buf_ipc) 	);
	memset(&buf_report	,0	,sizeof(buf_report) );

	if(net_open(&udp) != OK){return -1;}
	else {
		printf("###### net open ok!!\n");
		bInitUdp=1; return 0;
	}
}


int set_udpd(void)
{

//	if(SYSTEM.ID == ModuleA){
//		udp.grca.board_id = BOARD_SIDE_A;
//		//sprintf(udp.inven.inv_fname,"INV_BSC%02d_BTS%03d_GRCA00",udp.inven.inv_bsc_id,udp.inven.inv_bts_id);
//	}
//	else {
//		udp.grca.board_id = BOARD_SIDE_B;
//		//sprintf(udp.inven.inv_fname,"INV_BSC%02d_BTS%03d_GRCA01",udp.inven.inv_bsc_id,udp.inven.inv_bts_id);
//	}
//
//	if(access(BAKMODE_RAM_FILE,R_OK)){
//		udp.grca.boot_side = BOOT_SIDE_ORG;
//		sprintf(MESG,"Bootside ORG, %s", ((SYSTEM.ID==ModuleA)?"A-side":"B-side"));
//		LogItString(LOG_CATA1_NORM, LOG_CATA2_NOTHING, MESG);
//	}
//	else{
//		udp.grca.boot_side = BOOT_SIDE_BAK;
//		sprintf(MESG,"Bootside BAK, %s", ((SYSTEM.ID==ModuleA)?"A-side":"B-side"));
//		LogItString(LOG_CATA1_NORM, LOG_CATA2_NOTHING, MESG);
//	}
	return 0;
}


void close_udpd(void)
{
	net_close(&udp);
}

extern int TimeSliceCounter;

int iudpd=0;
void udpd(void)
{
int len;
TIME_INTERNAL_ wait = { 0, 0 };


	//hmlee - f/w download processing
	//if(TimeSliceCounter>80 && TimeSliceCounter<90){
		//fwup_do_state(&udp);
		//inv_do_state(&udp);
	//}


wait.seconds=0;
wait.nanoseconds=1000;

	//hmlee - wait for a packet
	if(net_select(&udp, &wait) <= 0) {return;}

	//hmlee - invalid packet
	if(net_recv(&udp) != OK) {return;}

//	printf(" 02##");
	udp_printf("\nreceive packet, raddr:%s, port:%d, len:%d\n",udp.net.raddr_temp,udp.net.rport_temp, udp.net.ibuf_len);
	//hmlee - packet too small for header
	if(udp.net.ibuf_len < IPC_KTI_HEADER_LENGTH){
		udp_printf("too short header:%d/%d\n",udp.net.ibuf_len, IPC_HEADER_LENGTH);
		//fwup_debug_fwdownload_start();
		return;
	}


//	else 	//fwup_debug_fwdownload_start();
//	udp_MemoryHexDump(udp.net.ibuf,udp.net.ibuf_len);

	//hmlee - see what we have
	//msg_unpack_header(udp.net.ibuf, &udp.msg.header_in);
	//msg_unpack_header(udp.net.ibuf, &udp.msg.in);
	msg_unpack_header(&udp);

	//msg_unpack_user_data(&udp);

//udp_printf("length         > %d\n", udp.msg.in.ipc.len);
//udp_printf("sig_id         > 0x%x\n", udp.msg.in.ipc.command);
//udp_printf("dst_tid        > %d\n", udp.msg.in.ipc.nickname);
//udp_printf("src_tid        > %d\n", udp.msg.in.ipc.sequence);

}

void udp_MemoryHexDump( void *address, int size )
{

	int lp1,lp2,lp3;
	unsigned char *ptrData;

	ptrData = (unsigned char*)address;
	if(!debug_out_udp){ return; }
	//AddDebug( "=======================================");
	udp_printf( "------------------------------------------------------------\n");

	//for( lp1 = 0; lp1 < size*4; lp1 += 16 )
	for( lp1 = 0; lp1 < size; lp1 += 16 )
	{
		//s += AnsiString().sprintf( "%04X-%04X :",  (((unsigned int)ptrData-(unsigned int)address)>>16)&0xFFFF,((unsigned int)ptrData-(unsigned int)address)     &0xFFFF  );
		udp_printf( "%04X :",((unsigned int)ptrData-(unsigned int)address)     &0xFFFF  );


	  	for( lp2 = 0; lp2 < 4; lp2++ )
		{
			//for( lp3 = 0; lp3 < 4; lp3++ )
	  		for( lp3 = 0; lp3 < 4 ; lp3++ )
			{
	  			if( (lp2 * 4 + lp3 + lp1)>=size ){
	  				udp_printf( "  ");
	  			}
	  			else udp_printf( "%02X", ptrData[ lp2 * 4 + lp3 ] & 0xFF );
			}
			udp_printf( " " );
		}
	  	udp_printf( "  " );
		//for( lp3 = 0; lp3 < 16; lp3++ )
	  	for( lp3 = 0; lp3 < 16 ; lp3++ )
		{
	  		if( (lp3 + lp1)>=size ){  udp_printf( " "); }
	  		else if      ( ptrData[lp3] < ' ' ) { udp_printf( "." ); }
			else if ( ptrData[lp3] > '~' ) {udp_printf( "." );	}
			else    {						udp_printf("%c", ptrData[lp3]  ); }
		}

		udp_printf( "\n" );
		ptrData += 16;
	}
	udp_printf( "------------------------------------------------------------\n\n");

}//---------------------------------------------------------------------------


